package com.chat.transmission.netty.handler;

import com.chat.common.dto.NettyUdpDto;
import com.chat.common.enums.NettyUdpPackageType;
import com.chat.transmission.event.event.UserGetMsgEvent;
import com.chat.transmission.event.publisher.EventPublisher;
import com.chat.transmission.event.event.UserSendMsgEvent;
import com.chat.transmission.event.source.GetMsgEventSource;
import com.chat.transmission.event.source.SendMsgEventSource;
import com.chat.transmission.util.ApplicationContextProvider;
import com.google.gson.Gson;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wei kunJie
 * @date 2024/3/22 16:16:25
 */
public class NettyTransferDataUdpHandler extends SimpleChannelInboundHandler<DatagramPacket> {


    private final Gson gson;
    private final EventPublisher eventPublisher;
    private final ConcurrentHashMap<String,Object> getMsgEventSourceMap;
    ;

    public NettyTransferDataUdpHandler() {
        this.gson = ApplicationContextProvider.getBean(Gson.class);
        this.eventPublisher = ApplicationContextProvider.getBean(EventPublisher.class);
        this.getMsgEventSourceMap=ApplicationContextProvider.getBean("getMsgEventSourceMap",ConcurrentHashMap.class);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        // 处理接收到的数据
        //获取本次udp包的网络地址
        InetSocketAddress sender = packet.sender();
        String json = packet.content().toString(CharsetUtil.UTF_8);
        // 接收到的用户udp包，解析json数据
        NettyUdpDto nettyUdpDto = gson.fromJson(json, NettyUdpDto.class);
        NettyUdpPackageType type=nettyUdpDto.getType();
        if (type.equals(NettyUdpPackageType.SEND_MSG)){//发送消息的udp包
            //发送消息事件
            SendMsgEventSource sendMsgEventSource = new SendMsgEventSource(sender, nettyUdpDto.getMessageDTO(), ctx);
            //发布一个用户发消息的事件
            eventPublisher.sendEvent(new UserSendMsgEvent(sendMsgEventSource));
        }else if (type.equals(NettyUdpPackageType.GET_MSG)){//心跳udp包，获取消息的udp包
//            System.out.println(json);//TODO：查看心跳情况
            //获取消息事件
            GetMsgEventSource getMsgEventSource = new GetMsgEventSource(nettyUdpDto.getToken(), sender,ctx);
            //先看看这个用户是不是正在获取但又来了一次，是就丢弃这次心跳
            //获取数据可能要一定的时间，避免在一次获取消息还没完成，这个用户又再次发来获取消息的请求（心跳）而造成资源浪费
            if (getMsgEventSourceMap.contains(getMsgEventSource)) {
                return;
            }
            getMsgEventSourceMap.put(getMsgEventSource.getToken(),getMsgEventSource.getToken());
            //发布获取消息事件
            eventPublisher.sendEvent(new UserGetMsgEvent(getMsgEventSource));
        }

    }
}

